//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>

#define _INFOID_LEN_ 32

#define INFO_GETVENDERID  0xA001
#define INFO_GETMODEL     0xA002
#define INFO_GETFIRMVER   0xA003
#define INFO_GETFIRMDATE  0xA004
#define INFO_GETSOFTVER   0xA005
#define INFO_GETSOFTDATE  0xA006
#define INFO_GETHARDVER   0xA007
#define INFO_GETHARDDATE  0xA008

typedef struct __info_struct {
    char*  VendorID;
    char*  ModelID;
    char*  FirmVer;
    char*  FirmData;
    char*  SoftVer;
    char*  SoftDate;
    char*  HardVer;
    char*  HartDate;
    char*  Unknown;
}info_stt, *pinfo_stt;

class VerInfo: public CDeviceDriver {
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf &buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf &inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    // It's Maybe have no use for the keyboard driver.
    virtual void Dispose() {}

    int Initialize();

public:
    info_stt m_sysinfo;

};


int VerInfo::Initialize()
{
    m_sysinfo.VendorID = "yuhua";
    m_sysinfo.ModelID  = "broadcom";
    m_sysinfo.FirmVer  = NULL;
    m_sysinfo.FirmData = NULL;
    m_sysinfo.SoftVer  = "elastos 2.0";
    m_sysinfo.SoftDate = __DATE__;
    m_sysinfo.HardVer  = "intel pxa270";
    m_sysinfo.HartDate = "2006-09-01";
    m_sysinfo.Unknown  = "Unknown";

    return 0;
}


ECode VerInfo::Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode VerInfo::Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf &buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode VerInfo::Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf &inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    ECode ec = NOERROR;
    if (pOutBuffer == NULL) {
        return E_INVALID_ARGUMENT;
    }
    char *pData = (char*)pOutBuffer->GetPayload();

    switch(nControlCode) {
        case INFO_GETVENDERID:
            strcpy(pData, m_sysinfo.VendorID);
            pOutBuffer->SetUsed(strlen(m_sysinfo.VendorID));
            break;

        case INFO_GETMODEL:
            strcpy(pData, m_sysinfo.ModelID);
            pOutBuffer->SetUsed(strlen(m_sysinfo.ModelID));
            break;

        case INFO_GETFIRMVER:
            strcpy(pData, m_sysinfo.Unknown);
            pOutBuffer->SetUsed(strlen(m_sysinfo.Unknown));
            ec = E_NOT_IMPLEMENTED;
            break;

        case INFO_GETFIRMDATE:
            strcpy(pData, m_sysinfo.Unknown);
            pOutBuffer->SetUsed(strlen(m_sysinfo.Unknown));
            ec = E_NOT_IMPLEMENTED;
            break;

        case INFO_GETSOFTVER:
            strcpy(pData, m_sysinfo.SoftVer);
            pOutBuffer->SetUsed(strlen(m_sysinfo.SoftVer));
            break;

        case INFO_GETSOFTDATE:
            strcpy(pData, m_sysinfo.SoftDate);
            pOutBuffer->SetUsed(strlen(m_sysinfo.SoftDate));
            break;

        case INFO_GETHARDVER:
            strcpy(pData, m_sysinfo.HardVer);
            pOutBuffer->SetUsed(strlen(m_sysinfo.HardVer));
            break;

        case INFO_GETHARDDATE:
            strcpy(pData, m_sysinfo.HartDate);
            pOutBuffer->SetUsed(strlen(m_sysinfo.HartDate));
            break;

        default:
            strcpy(pData, m_sysinfo.Unknown);
            pOutBuffer->SetUsed(strlen(m_sysinfo.Unknown));
            ec = E_NOT_IMPLEMENTED;
            break;

    }

    return ec;
}

VerInfo g_vinfo;

EXTERN IDeviceDriver * CDECL CreateVerInfo(uint_t uDeviceNo, void *pvParameter)
{
    g_vinfo.Initialize();
    //cprintf("Create NotiCenter %x\n", g_pNotiCenter);
    return (IDeviceDriver *)&g_vinfo;
}
